using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;

namespace ZombieHigh2.GameInput
{

    /* The GamePad buttons */
    public enum Buttons
    {
        A,
        B,
        X,
        Y,
        BACK,
        START,
        LSHOULDER,
        RSHOULDER,
        DPAD_UP,
        DPAD_LEFT,
        DPAD_DOWN,
        DPAD_RIGHT
    }

    /* The singleton InputManager class */
    /* Currently, this class only tests for Player One, but will be expanded to include */
    /* all the players from 1 - 4 */
    public class InputManager
    {
        List<Buttons> lastFrame;
        List<Buttons> thisFrame;
        Vector2 leftAnalog;
        Vector2 rightAnalog;
        float leftTrigger;
        float rightTrigger;
        Boolean controllerConnected;

        static InputManager instance = null;

        private InputManager()
        {
            lastFrame = new List<Buttons>();
            thisFrame = new List<Buttons>();
            controllerConnected = false;
        }

        /* Returns only a single instance of this class */
        public static InputManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new InputManager();
                }

                return instance;
            }
        }

        #region Properties
        public Vector2 LeftAnalog
        {
            get { return leftAnalog; }
        }

        public Vector2 RightAnalog
        {
            get { return rightAnalog; }
        }

        public float LeftTrigger
        {
            get { return leftTrigger; }
        }

        public float RightTrigger
        {
            get { return rightTrigger; }
        }

        /* Returns whether the players controller is connected */
        public Boolean IsConnected
        {
            get { return controllerConnected; }
        }

        #endregion

        /* Determines whether a button is pressed */
        public Boolean Pressed(Buttons button)
        {
            if (lastFrame.Contains(button))
            {
                //If in last frame, ignore it
                return false;
            }
            else if (thisFrame.Contains(button))
            {
                //Not in last frame, in this frame?
                return true;
            }

            return false;
        }

        /* This method should be called every frame */
        public void Update()
        {

            /* Add the old keys from the previous frame */
            lastFrame.Clear();
            foreach (Buttons button in thisFrame)
            {
                lastFrame.Add(button);
            }

            /* Check which keys are being pressed this frame */
            thisFrame.Clear();
            GamePadState gpadState = GamePad.GetState(PlayerIndex.One);

            if (gpadState.Buttons.A == ButtonState.Pressed)
                thisFrame.Add(Buttons.A);
            if (gpadState.Buttons.B == ButtonState.Pressed)
                thisFrame.Add(Buttons.B);
            if (gpadState.Buttons.X == ButtonState.Pressed)
                thisFrame.Add(Buttons.X);
            if (gpadState.Buttons.Y == ButtonState.Pressed)
                thisFrame.Add(Buttons.Y);
            if (gpadState.Buttons.Start == ButtonState.Pressed)
                thisFrame.Add(Buttons.START);
            if (gpadState.Buttons.Back == ButtonState.Pressed)
                thisFrame.Add(Buttons.BACK);

            if (gpadState.DPad.Up == ButtonState.Pressed)
                thisFrame.Add(Buttons.DPAD_UP);
            if (gpadState.DPad.Left == ButtonState.Pressed)
                thisFrame.Add(Buttons.DPAD_LEFT);
            if (gpadState.DPad.Down == ButtonState.Pressed)
                thisFrame.Add(Buttons.DPAD_DOWN);
            if (gpadState.DPad.Right == ButtonState.Pressed)
                thisFrame.Add(Buttons.DPAD_RIGHT);

            /* The thumb sticks */
            leftAnalog = gpadState.ThumbSticks.Left;
            rightAnalog = gpadState.ThumbSticks.Right;

            /* The triggers */
            leftTrigger = gpadState.Triggers.Left;
            rightTrigger = gpadState.Triggers.Right;
        }
    }
}